package com.ruoyi.project.digital.controller.api;

import cn.hutool.core.util.ObjectUtil;
/*import com.cl.unipay4j.core.Result;
import com.cl.unipay4j.core.pay.INotify;
import com.cl.unipay4j.core.pay.IPayment;
import com.cl.unipay4j.core.pay.PayModel;
import com.cl.unipay4j.core.pay.PayResponse;
import com.cl.unipay4j.wx.WxPayFactoryProvider;*/
import com.cl.unipay4j.core.Result;
import com.cl.unipay4j.core.pay.INotify;
import com.cl.unipay4j.core.pay.IPayment;
import com.cl.unipay4j.core.pay.PayModel;
import com.cl.unipay4j.core.pay.PayResponse;
import com.cl.unipay4j.wx.WxPayFactoryProvider;
import com.ruoyi.common.utils.AuthUtil;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.interceptor.annotation.RepeatSubmit;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.digital.domain.Apply;
import com.ruoyi.project.digital.domain.Payinfo;
import com.ruoyi.project.digital.domain.WechatUser;
import com.ruoyi.project.digital.domain.dto.LoginWechatUser;
import com.ruoyi.project.digital.domain.dto.PayDto;
import com.ruoyi.project.digital.domain.enums.ApplyStatus;
import com.ruoyi.project.digital.domain.enums.IsPay;
import com.ruoyi.project.digital.service.*;
import com.ruoyi.project.digital.utils.OrderUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 打印费用支付信息Controller
 *
 * @author ruoyi
 * @date 2020-12-17
 */
@Api(value = "支付相关接口", tags = "支付相关接口")
@RestController
@RequestMapping("api/wu/payinfo")
public class PayinfoApiController extends BaseController {
    @Autowired
    private IPayinfoService payinfoService;
    @Autowired
    private IApplyService applyService;
   @Autowired
    private WxPayFactoryProvider wxPayFactoryProvider;
    @Autowired
    private TemplateMsgService templateMsgService;
    @Autowired
    private IWechatUserService wechatUserService;
    @Autowired
    private MiniAppTemplateMsgService miniAppTemplateMsgService;

    @ApiOperation(value = "发起付款")
    @PostMapping("")
    @RepeatSubmit
    public AjaxResult pay(HttpServletRequest request, @RequestBody PayDto dto) {
        LoginWechatUser user = AuthUtil.getWechatUser();
        // 1、判断信息是否存在
        Payinfo payinfo = payinfoService.selectByApplyId(dto.getApplyId());
        if (null == payinfo) {
            return AjaxResult.error("信息不存在");
        }
        // 2.1、查看支付信息表中支付状态，如果状态为已支付，则给前台返回已支付提示
        if (IsPay.FINISHED_PAY.getValue().equals(payinfo.getIsPay())) {
            return AjaxResult.error("已支付，请勿重复发起");
        }
        payinfo.setPayNo(OrderUtil.genOrderNum(user.getId()));
        payinfoService.updatePayinfo(payinfo);
        // 支付配置信息
        IPayment payment = wxPayFactoryProvider.getPayment(dto.getTradeType());
        PayModel payModel = new PayModel();
        payModel.setOutTradeNo(payinfo.getPayNo());
        payModel.setPrice(payinfo.getTotalAmount());
        // payModel.setPrice(new BigDecimal("0.01"));
        payModel.setBody("打印总费用支付");
        payModel.setSpbillCreateIp(IpUtils.getIpAddr(request));
        payModel.setOpenid(user.getOpenId());
        Result<Object> payResult = payment.pay(payModel);
        return AjaxResult.success(payResult);
    }


    @ApiOperation(value = "支付回调")
    @PostMapping("/notify/paySuccess")
    public void notify(HttpServletRequest request, HttpServletResponse response) {
        INotify notify = wxPayFactoryProvider.getNotify();
        Result<PayResponse> notifyResult = notify.execNotify(request);
        String returnMsg = notify.failMsg();
        if (notifyResult.isReturnSuccess()) {
            if (!notifyResult.isInvalidSign()) {
                PayResponse payResponse = notifyResult.getData();
                // 平台订单号
                String outTradeNo = payResponse.getOutTradeNo();
                // 通道订单号
                String tradeNo = payResponse.getTradeNo();
                Payinfo payinfo = payinfoService.selectByPayNo(outTradeNo);
                if(ObjectUtil.isEmpty(payinfo)){
                    logger.info("支付信息查询为空，outTradeNo："+outTradeNo);
                }else if(payinfo.getIsPay().equals(IsPay.FINISHED_PAY.getValue())){ //判断是否重复回调
                    logger.info("已支付，重复回调，outTradeNo："+outTradeNo);
                }else if (notifyResult.isTradeSuccess()) { // 判断交易是否成功
                    payinfo.setSerialNo(tradeNo);
                    payinfo.setIsPay(IsPay.FINISHED_PAY.getValue());
                    payinfo.setPayTime(new Date());
                    payinfoService.updatePayinfo(payinfo);
                    //变更申请状态为已支付
                    Apply apply = applyService.selectApplyById(payinfo.getApplyId());
                    apply.setStatus(ApplyStatus.FINISHED_PAY.getValue());
                    applyService.updateApply(apply);
                    //模板消息 已支付通知
                    WechatUser wu=wechatUserService.selectWechatUserById(apply.getUserId());
                    //公众号消息
                    //templateMsgService.finidedPayMsg(apply.getId(),wu.getOpenId(),apply.getApplyNo(),apply.getName(),payinfo.getTotalAmount(),payinfo.getPayTime().toString());
                   //小程序消息
                    miniAppTemplateMsgService.finidedPayMsg(apply.getId(),wu.getOpenId(),apply.getApplyNo(),payinfo.getTotalAmount());
                    returnMsg = notify.successMsg();
                }
            } else {
                logger.info("验签失败");
            }
        }

        PrintWriter pw = null;
        try {
            response.reset();
            pw = response.getWriter();
            pw.write(returnMsg);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != pw) {
                pw.close();
            }
        }
    }
}
